﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Threading;

namespace Sofire.DataComm.Net.Async
{
    /// <summary>
    /// 表示异步套接字操作。包含一个 <see cref="AsyncSocketReceiveEventArgs"/> 实例和一个 <see cref="AsyncSocketSendEventArgs"/> 实例。并支持对 Send 操作时的线程控制（保证单发）。
    /// </summary>
    internal class SocketAsyncEventArgsClient : SocketAsyncEventArgs
    {
        /// <summary>
        /// 接收时专用。
        /// </summary>
        internal ReceiveTranslater BufferHandler;

        internal readonly AsyncSocketReceiveEventArgs RaiseReceiveEventArgs;
        internal readonly AsyncSocketSendEventArgs RaiseSendEventArgs;

        private AutoResetEvent SendResetEvent;

        private bool _IsBusy;
        /// <summary>
        /// 设置或获取一个值，指示当前对象是否处于繁忙状态。
        /// </summary>
        public bool IsBusy
        {
            get
            {
                lock(this) return this._IsBusy;
            }
            internal set
            {
                lock(this) this._IsBusy = value;
            }
        }

        /// <summary>
        /// 设置或获取一个值，指示当前对象是否处于连接状态。
        /// </summary>
        public virtual bool IsConnected
        {
            get
            {
                return true;
            }
        }

#if SILVERLIGHT
        /// <summary>
        /// 获取或设置要使用的套接字或创建用于接受与异步套接字方法的连接的套接字。
        /// </summary>
        public Socket AcceptSocket { get; set; }
#endif

        public SocketAsyncEventArgsClient()
        {
            RaiseReceiveEventArgs = new AsyncSocketReceiveEventArgs(this);
            RaiseSendEventArgs = new AsyncSocketSendEventArgs(this);
        }

        public SocketAsyncEventArgsClient(bool createReceiveEventArgs, bool createSendEventArgs)
        {
            if(createReceiveEventArgs) RaiseReceiveEventArgs = new AsyncSocketReceiveEventArgs(this);

            if(createSendEventArgs) RaiseSendEventArgs = new AsyncSocketSendEventArgs(this);
        }

        public void InitSendMode()
        {
            if(SendResetEvent == null)
            {
                SendResetEvent = new AutoResetEvent(true);
            }
        }

        public void WaitOne()
        {
            SendResetEvent.WaitOne();
        }

        public void Set()
        {
            if(SendResetEvent != null) SendResetEvent.Set();
        }
    }
}
